package zclients

import (
	"context"
	"encoding/json"
	"github.com/pkg/errors"
	"github.com/uber/tchannel-go/thrift"
	"go.didapinche.com/foundation/plat-echo/app/ops/models"
	"go.didapinche.com/foundation/plat-echo/pkg/utils/data"
	"go.didapinche.com/goapi/plat_limos_rpc"
	dtime "go.didapinche.com/time"
	"go.didapinche.com/zeus-go/v2"
	"go.didapinche.com/zeus-go/v2/client"
	"strconv"
	"strings"
	"time"
)

func NewLimosService(z *zeus.Zeus) (plat_limos_rpc.TChanLimosService, error) {
	c, err := client.New(z, "LimosService")
	if err != nil {
		//return nil, errors.Wrap(err, "create zeus LimosService error")
		return nil, nil
	}

	tc := plat_limos_rpc.NewTChanLimosServiceClient(c)

	return tc, nil
}

func FindAppByID(ctx context.Context, p plat_limos_rpc.TChanLimosService, id uint64) (*plat_limos_rpc.App, error) {
	context2, _ := context.WithTimeout(ctx, 5*time.Second)
	ctx2 := thrift.Wrap(context2)
	app, err := p.GetAppByID(ctx2, int64(id))
	if err != nil {
		return nil, errors.Wrap(err, "call limosService.GetAppByID err")
	}

	return app, nil
}

func FindApp(ctx context.Context, p plat_limos_rpc.TChanLimosService) (*plat_limos_rpc.AppsForPage, error) {
	context2, _ := context.WithTimeout(ctx, 5*time.Second)
	ctx2 := thrift.Wrap(context2)
	page, err := p.FindAppForPage(ctx2, "", "", "", "", "", 0, "all", 10000, 1, "", 0)
	if err != nil {
		return nil, errors.Wrap(err, "call limosService.FindAppForPage err")
	}

	return page, nil
}

func FindHost(ctx context.Context, p plat_limos_rpc.TChanLimosService) (*plat_limos_rpc.HostResourceList, error) {
	context2, _ := context.WithTimeout(ctx, 5*time.Second)
	ctx2 := thrift.Wrap(context2)
	page, err := p.QueryHostResource(ctx2, 0, "", "", "", "", 0, 1000)
	if err != nil {
		return nil, errors.Wrap(err, "call limosService.FindAppForPage err")
	}

	return page, nil
}

// 查询应用部署ip，返回ip1｜ip2｜ip3格式
func FindIP(ctx context.Context, p plat_limos_rpc.TChanLimosService, appID uint64, env string) (string, error) {
	ip := ""
	context2, _ := context.WithTimeout(ctx, 5*time.Second)
	ctx2 := thrift.Wrap(context2)
	var envID []int64
	if strings.Contains(env, ",") {
		split := strings.Split(env, ",")
		for _, s := range split {
			id, _ := strconv.ParseInt(s, 10, 64)
			envID = append(envID, id)
		}
	} else {
		id, _ := strconv.ParseInt(env, 10, 64)
		envID = append(envID, id)
	}
	for _, id := range envID {
		hosts, err := p.FindRelateHostsByAppAndEnv(ctx2, int64(appID), int32(id))
		if err == nil {
			for _, host := range hosts {
				ip = ip + host.IP + "|"
			}
		}
	}
	if len(ip) > 1 {
		ip = ip[0 : len(ip)-1]
	}

	return ip, nil
}

// 查询应用运行pid
func FindPid(ctx context.Context, p plat_limos_rpc.TChanLimosService, appID uint64, env string) (string, error) {
	pid := ""
	context2, _ := context.WithTimeout(ctx, 5*time.Second)
	ctx2 := thrift.Wrap(context2)
	var envID []int64
	if strings.Contains(env, ",") {
		split := strings.Split(env, ",")
		for _, s := range split {
			id, _ := strconv.ParseInt(s, 10, 64)
			envID = append(envID, id)
		}
	} else {
		id, _ := strconv.ParseInt(env, 10, 64)
		envID = append(envID, id)
	}
	for _, id := range envID {
		deployInfos, err := p.GetAppDeployInfo(ctx2, int64(appID), id)
		if err == nil {
			for _, info := range deployInfos {
				pid = pid + strconv.FormatInt(info.Pid, 10) + "|"
			}
		}
	}
	if len(pid) > 1 {
		pid = pid[0 : len(pid)-1]
	}

	return pid, nil
}

//将limos的app转化为models.Application
func ConvertApp(app *plat_limos_rpc.App, owners []*models.ApplicationOwner) *models.Application {
	application := new(models.Application)
	application.ID = uint64(app.ID)
	application.Name = app.Name
	application.DevGroupID = app.DevGroupID
	application.Description = app.Description
	createTime, err := time.Parse(data.FormatLayout, app.CreateTime)
	if err == nil {
		application.CreateTime = dtime.Time{createTime}
	}
	updateTime, err := time.Parse(data.FormatLayout, app.UpdateTime)
	if err == nil {
		application.UpdateTime = dtime.Time{updateTime}
	}
	if len(owners) > 0 {
		bytes, e := json.Marshal(owners)
		if e != nil {
			return nil
		}
		application.Owner = string(bytes)
	}
	application.Level = int(app.Level)
	application.Language = app.Language
	application.GitURL = app.GitURL
	application.DevGroupName = app.DevGroupName
	return application
}
